home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / vidhrdw / offtwall.c < prev    next >
C/C++ Source or Header  |  2000-04-04  |  10KB  |  367 lines

  1. /***************************************************************************
  2.  
  3.   vidhrdw/offtwall.c
  4.  
  5.   Functions to emulate the video hardware of the machine.
  6.  
  7. ****************************************************************************
  8.  
  9.     Playfield encoding
  10.     ------------------
  11.         1 16-bit word is used
  12.  
  13.         Word 1:
  14.             Bits 13-15 = palette
  15.             Bits  0-12 = image number
  16.  
  17.  
  18.     Motion Object encoding
  19.     ----------------------
  20.         4 16-bit words are used
  21.  
  22.         Word 1:
  23.             Bits  0-7  = link to the next motion object
  24.  
  25.         Word 2:
  26.             Bits  0-11 = image index
  27.  
  28.         Word 3:
  29.             Bits  7-15 = horizontal position
  30.             Bits  0-3  = motion object palette
  31.  
  32.         Word 4:
  33.             Bits  7-15 = vertical position
  34.             Bits  4-6  = horizontal size of the object, in tiles
  35.             Bit   3    = horizontal flip
  36.             Bits  0-2  = vertical size of the object, in tiles
  37.  
  38. ***************************************************************************/
  39.  
  40. #include "driver.h"
  41. #include "machine/atarigen.h"
  42. #include "vidhrdw/generic.h"
  43.  
  44. #define XCHARS 42
  45. #define YCHARS 30
  46.  
  47. #define XDIM (XCHARS*8)
  48. #define YDIM (YCHARS*8)
  49.  
  50.  
  51.  
  52. /*************************************
  53.  *
  54.  *    Prototypes
  55.  *
  56.  *************************************/
  57.  
  58. static const UINT8 *update_palette(void);
  59.  
  60. static void pf_color_callback(const struct rectangle *clip, const struct rectangle *tiles, const struct atarigen_pf_state *state, void *data);
  61. static void pf_render_callback(const struct rectangle *clip, const struct rectangle *tiles, const struct atarigen_pf_state *state, void *data);
  62.  
  63. static void mo_color_callback(const UINT16 *data, const struct rectangle *clip, void *param);
  64. static void mo_render_callback(const UINT16 *data, const struct rectangle *clip, void *param);
  65.  
  66.  
  67.  
  68. /*************************************
  69.  *
  70.  *    Video system start
  71.  *
  72.  *************************************/
  73.  
  74. int offtwall_vh_start(void)
  75. {
  76.     static struct atarigen_mo_desc mo_desc =
  77.     {
  78.         256,                 /* maximum number of MO's */
  79.         8,                   /* number of bytes per MO entry */
  80.         2,                   /* number of bytes between MO words */
  81.         0,                   /* ignore an entry if this word == 0xffff */
  82.         0, 0, 0xff,          /* link = (data[linkword] >> linkshift) & linkmask */
  83.         0                    /* render in reverse link order */
  84.     };
  85.  
  86.     static struct atarigen_pf_desc pf_desc =
  87.     {
  88.         8, 8,                /* width/height of each tile */
  89.         64, 64,                /* number of tiles in each direction */
  90.         1                    /* non-scrolling */
  91.     };
  92.  
  93.     /* initialize the playfield */
  94.     if (atarigen_pf_init(&pf_desc))
  95.         return 1;
  96.  
  97.     /* initialize the motion objects */
  98.     if (atarigen_mo_init(&mo_desc))
  99.     {
  100.         atarigen_pf_free();
  101.         return 1;
  102.     }
  103.  
  104.     return 0;
  105. }
  106.  
  107.  
  108.  
  109. /*************************************
  110.  *
  111.  *    Video system shutdown
  112.  *
  113.  *************************************/
  114.  
  115. void offtwall_vh_stop(void)
  116. {
  117.     atarigen_pf_free();
  118.     atarigen_mo_free();
  119. }
  120.  
  121.  
  122.  
  123. /*************************************
  124.  *
  125.  *    Playfield RAM write handler
  126.  *
  127.  *************************************/
  128.  
  129. WRITE_HANDLER( offtwall_playfieldram_w )
  130. {
  131.     int oldword = READ_WORD(&atarigen_playfieldram[offset]);
  132.     int newword = COMBINE_WORD(oldword, data);
  133.  
  134.     if (oldword != newword)
  135.     {
  136.         WRITE_WORD(&atarigen_playfieldram[offset], newword);
  137.         atarigen_pf_dirty[(offset & 0x1fff) / 2] = 0xff;
  138.     }
  139.  
  140.     /* handle the latch, but only write the upper byte */
  141.     if (offset < 0x2000 && atarigen_video_control_state.latch1 != -1)
  142.         offtwall_playfieldram_w(offset + 0x2000, atarigen_video_control_state.latch1 | 0x00ff0000);
  143. }
  144.  
  145.  
  146.  
  147. /*************************************
  148.  *
  149.  *    Periodic scanline updater
  150.  *
  151.  *************************************/
  152.  
  153. void offtwall_scanline_update(int scanline)
  154. {
  155.     /* update the playfield */
  156.     if (scanline == 0)
  157.         atarigen_video_control_update(&atarigen_playfieldram[0x1f00]);
  158.  
  159.     /* update the MOs from the SLIP table */
  160.     atarigen_mo_update_slip_512(atarigen_spriteram, atarigen_video_control_state.sprite_yscroll, scanline, &atarigen_playfieldram[0x1f80]);
  161. }
  162.  
  163.  
  164.  
  165. /*************************************
  166.  *
  167.  *    Main refresh
  168.  *
  169.  *************************************/
  170.  
  171. void offtwall_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
  172. {
  173.     /* remap if necessary */
  174.     if (update_palette())
  175.         memset(atarigen_pf_dirty, 0xff, atarigen_playfieldram_size / 4);
  176.  
  177.     /* update playfield */
  178.     atarigen_pf_process(pf_render_callback, bitmap, &Machine->drv->visible_area);
  179.  
  180.     /* render the motion objects */
  181.     atarigen_mo_process(mo_render_callback, bitmap);
  182.  
  183.     /* update onscreen messages */
  184.     atarigen_update_messages();
  185. }
  186.  
  187.  
  188.  
  189. /*************************************
  190.  *
  191.  *    Palette management
  192.  *
  193.  *************************************/
  194.  
  195. static const UINT8 *update_palette(void)
  196. {
  197.     UINT16 mo_map[16], pf_map[16];
  198.     int i, j;
  199.  
  200.     /* reset color tracking */
  201.     memset(mo_map, 0, sizeof(mo_map));
  202.     memset(pf_map, 0, sizeof(pf_map));
  203.     palette_init_used_colors();
  204.  
  205.     /* update color usage for the playfield */
  206.     atarigen_pf_process(pf_color_callback, pf_map, &Machine->drv->visible_area);
  207.  
  208.     /* update color usage for the mo's */
  209.     atarigen_mo_process(mo_color_callback, mo_map);
  210.  
  211.     /* rebuild the playfield palette */
  212.     for (i = 0; i < 16; i++)
  213.     {
  214.         UINT16 used = pf_map[i];
  215.         if (used)
  216.             for (j = 0; j < 16; j++)
  217.                 if (used & (1 << j))
  218.                     palette_used_colors[0x200 + i * 16 + j] = PALETTE_COLOR_USED;
  219.     }
  220.  
  221.     /* rebuild the motion object palette */
  222.     for (i = 0; i < 16; i++)
  223.     {
  224.         UINT16 used = mo_map[i];
  225.         if (used)
  226.         {
  227.             palette_used_colors[0x100 + i * 16 + 0] = PALETTE_COLOR_TRANSPARENT;
  228.             for (j = 1; j < 16; j++)
  229.                 if (used & (1 << j))
  230.                     palette_used_colors[0x100 + i * 16 + j] = PALETTE_COLOR_USED;
  231.         }
  232.     }
  233.  
  234.     return palette_recalc();
  235. }
  236.  
  237.  
  238.  
  239. /*************************************
  240.  *
  241.  *    Playfield palette
  242.  *
  243.  *************************************/
  244.  
  245. static void pf_color_callback(const struct rectangle *clip, const struct rectangle *tiles, const struct atarigen_pf_state *state, void *param)
  246. {
  247.     const unsigned int *usage = Machine->gfx[0]->pen_usage;
  248.     UINT16 *colormap = param;
  249.     int x, y;
  250.  
  251.     /* standard loop over tiles */
  252.     for (x = tiles->min_x; x != tiles->max_x; x = (x + 1) & 63)
  253.         for (y = tiles->min_y; y != tiles->max_y; y = (y + 1) & 63)
  254.         {
  255.             int offs = x * 64 + y;
  256.             int data1 = READ_WORD(&atarigen_playfieldram[offs * 2]);
  257.             int data2 = READ_WORD(&atarigen_playfieldram[offs * 2 + 0x2000]);
  258.             int code = data1 & 0x7fff;
  259.             int color = (data2 >> 8) & 15;
  260.  
  261.             /* mark the colors used by this tile */
  262.             colormap[color] |= usage[code];
  263.         }
  264. }
  265.  
  266.  
  267.  
  268. /*************************************
  269.  *
  270.  *    Playfield rendering
  271.  *
  272.  *************************************/
  273.  
  274. static void pf_render_callback(const struct rectangle *clip, const struct rectangle *tiles, const struct atarigen_pf_state *state, void *param)
  275. {
  276.     const struct GfxElement *gfx = Machine->gfx[0];
  277.     struct osd_bitmap *bitmap = param;
  278.     int x, y;
  279.  
  280.     /* standard loop over tiles */
  281.     for (x = tiles->min_x; x != tiles->max_x; x = (x + 1) & 63)
  282.         for (y = tiles->min_y; y != tiles->max_y; y = (y + 1) & 63)
  283.         {
  284.             int offs = x * 64 + y;
  285.  
  286.             /* update only if dirty */
  287.             if (atarigen_pf_dirty[offs])
  288.             {
  289.                 int data1 = READ_WORD(&atarigen_playfieldram[offs * 2]);
  290.                 int data2 = READ_WORD(&atarigen_playfieldram[offs * 2 + 0x2000]);
  291.                 int color = (data2 >> 8) & 15;
  292.                 int hflip = data1 & 0x8000;
  293.                 int code = data1 & 0x7fff;
  294.  
  295.                 drawgfx(atarigen_pf_bitmap, gfx, code, 0x10 + color, hflip, 0, 8 * x, 8 * y, 0, TRANSPARENCY_NONE, 0);
  296.                 atarigen_pf_dirty[offs] = 0;
  297.             }
  298.         }
  299.  
  300.     /* then blast the result */
  301.     copybitmap(bitmap, atarigen_pf_bitmap, 0, 0, 0, 0, clip, TRANSPARENCY_NONE, 0);
  302. }
  303.  
  304.  
  305.  
  306. /*************************************
  307.  *
  308.  *    Motion object palette
  309.  *
  310.  *************************************/
  311.  
  312. static void mo_color_callback(const UINT16 *data, const struct rectangle *clip, void *param)
  313. {
  314.     const unsigned int *usage = Machine->gfx[0]->pen_usage;
  315.     UINT16 *colormap = param;
  316.     int code = data[1] & 0x7fff;
  317.     int color = data[2] & 0x000f;
  318.     int hsize = ((data[3] >> 4) & 7) + 1;
  319.     int vsize = (data[3] & 7) + 1;
  320.     int tiles = hsize * vsize;
  321.     UINT16 temp = 0;
  322.     int i;
  323.  
  324.     for (i = 0; i < tiles; i++)
  325.         temp |= usage[code++];
  326.     colormap[color] |= temp;
  327. }
  328.  
  329.  
  330.  
  331. /*************************************
  332.  *
  333.  *    Motion object rendering
  334.  *
  335.  *************************************/
  336.  
  337. static void mo_render_callback(const UINT16 *data, const struct rectangle *clip, void *param)
  338. {
  339.     const struct GfxElement *gfx = Machine->gfx[0];
  340.     struct osd_bitmap *bitmap = param;
  341.     struct rectangle pf_clip;
  342.  
  343.     /* extract data from the various words */
  344.     int hflip = data[1] & 0x8000;
  345.     int code = data[1] & 0x7fff;
  346.     int xpos = (data[2] >> 7) - atarigen_video_control_state.sprite_xscroll;
  347.     int color = data[2] & 0x000f;
  348.     int ypos = -(data[3] >> 7) - atarigen_video_control_state.sprite_yscroll;
  349.     int hsize = ((data[3] >> 4) & 7) + 1;
  350.     int vsize = (data[3] & 7) + 1;
  351.  
  352.     /* adjust for height */
  353.     ypos -= vsize * 8;
  354.  
  355.     /* adjust the final coordinates */
  356.     xpos &= 0x1ff;
  357.     ypos &= 0x1ff;
  358.     if (xpos >= XDIM) xpos -= 0x200;
  359.     if (ypos >= YDIM) ypos -= 0x200;
  360.  
  361.     /* determine the bounding box */
  362.     atarigen_mo_compute_clip_8x8(pf_clip, xpos, ypos, hsize, vsize, clip);
  363.  
  364.     /* draw the motion object */
  365.     atarigen_mo_draw_8x8(bitmap, gfx, code, color, hflip, 0, xpos, ypos, hsize, vsize, clip, TRANSPARENCY_PEN, 0);
  366. }
  367.